package com.baidu.ocrgeneralocrdemo;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import static android.Manifest.permission.CAMERA;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

public class TestCameraStreamActivity extends AppCompatActivity implements Camera.PreviewCallback {
    private static final String TAG = "CameraActivity";
    private ImageView cameraImgView = null;
    private TextView cameraStreamPredictResultView = null;
    private Activity activity = null;

    private final int DEFAULT_WIDTH = 640;
    private final int DEFAULT_HEIGHT = 480;
    private Camera mCamera = null;
    private static SurfaceTexture mPreviewTexture = new SurfaceTexture(1314);

    Timer timer = null;
    TimerTask task = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_camera_stream);

        activity = this;
        cameraImgView = findViewById(R.id.camera_stream_iamge);
        cameraStreamPredictResultView = findViewById(R.id.camera_stream_predict_result);

        Button btOpenCamera = findViewById(R.id.bt_open_camera);
        btOpenCamera.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 使用摄像头数据流进行测试
                openFrontalCamera(30);
            }
        });

        // 创建可以定时进行自动对焦的timer
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                if (mCamera != null) {
                    mCamera.autoFocus(new Camera.AutoFocusCallback() {
                        public void onAutoFocus(boolean success, Camera camera) {
                            Log.e(TAG, "onAutoFocus: " + success);
                        }
                    });
                }
            }
        };
    }

    @Override
    protected void onStop() {
        super.onStop();

    }

    @Override
    protected void onPause() {
        super.onPause();

        timer.cancel();
        if (mCamera != null) {
            mCamera.stopPreview();
        }
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Log.e(TAG, "onPreviewFrame");

        long startTime = System.currentTimeMillis();
        Bitmap originBmp = yuv2BitmapAndroid(data, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        long endTime = System.currentTimeMillis();
        Log.e(TAG, "yuv2Bitmap: " + (endTime - startTime) + "ms");

        Matrix matrix = new Matrix();
        matrix.postScale(-1, 1);
        matrix.setRotate(90);

        Bitmap newBitmap2 = Bitmap.createBitmap(originBmp, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT, matrix, true);
        newBitmap2 =  Bitmap.createBitmap(newBitmap2, 0, newBitmap2.getHeight() / 10,
                newBitmap2.getWidth(), newBitmap2.getHeight() / 3, null, false);

        boolean ret = PredictorWrapper.asyncTestOneImage(activity, newBitmap2,
                cameraImgView, cameraStreamPredictResultView, new PredictorResultListener() {
                    @Override
                    public void ResultListener(String result) throws IOException {

                    }
                });

        if (ret) {
            timer.cancel();
            if (mCamera != null) {
                timer.cancel();
                mCamera.stopPreview();
            }
        }
    }

    /**
     * 打开相机，默认打开前置相机
     *
     * @param expectFps
     */
    public void openFrontalCamera(int expectFps) {
        if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
            Log.e(TAG, "no CameraPermission error");
            return;
        }

        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                if (mCamera != null) {
                    mCamera.autoFocus(new Camera.AutoFocusCallback() {
                        public void onAutoFocus(boolean success, Camera camera) {
                            Log.e(TAG, "onAutoFocus: " + success);
                        }
                    });
                }
            }
        };

        if (mCamera != null) {
            mCamera.startPreview();
            timer.schedule(task, 1000, 1000);
            return;
        }

        Camera.CameraInfo info = new Camera.CameraInfo();
        boolean canUseCamera = true;

        int numCameras = Camera.getNumberOfCameras();
        try {
            for (int i = 0; i < numCameras; i++) {
                Camera.getCameraInfo(i, info);
                if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    mCamera = Camera.open(i);
                    break;
                }
            }
            // 如果没有前置摄像头，则打开默认的后置摄像头
            if (mCamera == null) {
                mCamera = Camera.open();
            }
        } catch (Exception e) {
            canUseCamera = false;
        }

        if (!canUseCamera) {
            return;
        }

        // 没有摄像头时，抛出异常
        if (mCamera == null) {
            return;
        }

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setRecordingHint(true);
        mCamera.setDisplayOrientation(0);
        parameters.setPreviewSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        mCamera.setParameters(parameters);

        try {
            mCamera.setPreviewTexture(mPreviewTexture);
            mCamera.setPreviewCallback(this);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }

        timer.schedule(task, 1000, 1000);
    }

    public static Bitmap yuv2BitmapAndroid(byte[] data, int width, int height) {
        Bitmap bmp = null;
        try {
            YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);
            if (image != null) {
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                image.compressToJpeg(new Rect(0, 0, width, height), 80, stream);

                bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                stream.close();
            }
        } catch (Exception ex) {
            Log.e("Sys", "Error:" + ex.getMessage());
        }

        return bmp;
    }
}
